package com.hu.bgp.server;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;

import com.hu.bgp.exceptions.BgpServerException;
import com.hu.bgp.util.ExtensionOnlyFilter;
import com.hu.bgp.util.JarClassLoader;
import com.hu.bgp.util.JarUtil;

/**
 * Verantwoordlijk voor het laden van gametypes uit 'bar'-archives.
 * 
 * @author ejvos
 */
public class BarLoader
{
	private JarClassLoader classLoader = new JarClassLoader();
	private GameServerContext gsc;

	public BarLoader(GameServerContext gsc)
	{
		this.gsc = gsc;
	}

	public void load(File barArchive)
	{
		// extract it
		File barExtractDir = new File(gsc.getConfiguration().getBarExtractPath() + File.separator + barArchive.getName());
		if (!barExtractDir.exists())
		{
			barExtractDir.mkdirs();
		}
		JarUtil.extract(barArchive, barExtractDir);

		// read bar configuration
		File barConfigFile = new File(barExtractDir.getAbsolutePath() + File.separator + gsc.getConfiguration().getBarConfigFilename());
		Properties p = new Properties();
		String alias = null;
		String displayName = null;
		String description = null;
		String mainClassFullName = null;
		try
		{
			FileInputStream fis = new FileInputStream(barConfigFile);
			p.load(fis);
			try
			{
				fis.close();
			}
			catch (IOException e)
			{
				// ignored
			}
			alias = p.getProperty("alias");
			displayName = p.getProperty("displayname");
			description = p.getProperty("description");
			mainClassFullName = p.getProperty("serverclass");
		}
		catch (FileNotFoundException e)
		{
			throw new BgpServerException("Could not load config.", e);
		}
		catch (IOException e)
		{
			throw new BgpServerException("Could not load config.", e);
		}

		// search class file
		Class<?> serverClass = null;
		for (File barArchiveEntry : barExtractDir.listFiles(new ExtensionOnlyFilter(".class")))
		{
			try
			{
				serverClass = classLoader.loadFromFile(mainClassFullName, barArchiveEntry);
			}
			catch (ClassNotFoundException e)
			{
				throw new BgpServerException("Could not load a class.", e);
			}
		}

		// add to the collection
		GameType gt = new GameType(gsc, barArchive, barExtractDir, serverClass, alias, displayName, description);
		gsc.getGameTypeCollection().add(gt);

		// if bgp is configured to immediately activate games after load
		if (gsc.getConfiguration().getBarDirectActivate())
		{
			gt.activate();
		}
	}
}
